package bg.btanev.eightyfour.client.presenter;

import bg.btanev.eightyfour.client.service.GWTCommandServiceAsync;
import bg.btanev.eightyfour.shared.command.CommandResult;
import bg.btanev.eightyfour.shared.command.person.FindPersonCommand;
import bg.btanev.eightyfour.shared.command.person.FindPersonInput;
import bg.btanev.eightyfour.shared.dto.TargetDto;
import bg.btanev.eightyfour.shared.dto.person.AddressDto;
import bg.btanev.eightyfour.shared.dto.person.ContactInfoDto;
import bg.btanev.eightyfour.shared.dto.person.PersonDto;
import bg.btanev.eightyfour.shared.dto.person.PersonNameDto;

import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;

/**
 *
 * @author B.Tanev
 *
 */
public class PersonPresenter implements Presenter {

	public static interface PersonDisplay extends Display {
		HasText getFirstNameData();

		HasText getSurnameData();

		HasText getLastNameData();

		HasText getEmailData();

		HasText getTelephoneData();

		HasText getWebsiteData();

		HasText getCountryData();

		HasText getCityData();

		HasText getStreetData();

		boolean isValid();

		HasClickHandlers getSaveClickHandlers();
	}

	@SuppressWarnings("unchecked")
	private final GWTCommandServiceAsync rpcService;
	private final PersonDisplay display;
	private final TargetDto target;
	private PersonDto person;

	@SuppressWarnings("unchecked")
	public PersonPresenter(GWTCommandServiceAsync rpcService, PersonDisplay display, TargetDto target) {
		this.rpcService = rpcService;
		this.display = display;
		this.target = target;
	}

	@Override
	public void go(HasWidgets container) {
		container.clear();
		updateView();
		container.add(display.asWidget());
	}

	public PersonDto getPersonFromView() {
		if (!(display.isValid())) {
			return null;
		}

		String firstName = display.getFirstNameData().getText();
		String surName = display.getSurnameData().getText();
		String lastName = display.getLastNameData().getText();

		firstName = firstName != null && firstName.trim().length() > 0 ? firstName.trim() : null;
		surName = surName != null && surName.trim().length() > 0 ? surName.trim() : null;
		lastName = lastName != null && lastName.trim().length() > 0 ? lastName.trim() : null;
		PersonNameDto personName = new PersonNameDto(firstName, surName, lastName);

		String email = display.getEmailData().getText();
		String phone = display.getTelephoneData().getText();
		String site = display.getWebsiteData().getText();

		email = email != null && email.trim().length() > 0 ? email.trim() : null;
		phone = phone != null && phone.trim().length() > 0 ? phone.trim() : null;
		site = site != null && site.trim().length() > 0 ? site.trim() : null;
		ContactInfoDto contactInfo = new ContactInfoDto(email, phone, site);

		String country = display.getCountryData().getText();
		String city = display.getCityData().getText();
		String street = display.getStreetData().getText();

		country = country != null && country.trim().length() > 0 ? country.trim() : null;
		city = city != null && city.trim().length() > 0 ? city.trim() : null;
		street = street != null && street.trim().length() > 0 ? street.trim() : null;
		AddressDto address = new AddressDto(country, city, street);
		contactInfo.setAddress(address);

		PersonDto person = new PersonDto(personName, contactInfo);
		if (target != null) {
			PersonDto oldPerson = target.getPerson();
			if (oldPerson != null) {
				person.setId(oldPerson.getId());
			}
		}
		return person;
	}

	public HasClickHandlers getSaveClickhandler() {
		return display.getSaveClickHandlers();
	}

	private void clearView() {
		display.getCityData().setText("");
		display.getCountryData().setText("");
		display.getEmailData().setText("");
		display.getFirstNameData().setText("");
		display.getLastNameData().setText("");
		display.getStreetData().setText("");
		display.getSurnameData().setText("");
		display.getTelephoneData().setText("");
		display.getWebsiteData().setText("");
	}

	@SuppressWarnings("unchecked")
	private void updateView() {
		setPerson(null);

		if (target == null || target.getId() == null || target.getId().longValue() <= 0) {
			return;
		}

		FindPersonCommand findPersonCommand = new FindPersonCommand();
		FindPersonInput commandInput = new FindPersonInput();
		commandInput.setTargetId(target.getId());
		PersonDto person = null;
		if ((person = target.getPerson()) != null) {
			commandInput.setPersonId(person.getId());
			if (person.getContactInfo() != null) {
				commandInput.setEmail(person.getContactInfo().getEmail());
			}
		}

		findPersonCommand.setInput(commandInput);
		rpcService.executeCommand(findPersonCommand, new AsyncCallback<CommandResult<FindPersonInput, PersonDto>>() {

			@Override
			public void onFailure(Throwable caught) {
				clearView();
			}

			@Override
			public void onSuccess(CommandResult<FindPersonInput, PersonDto> result) {
				if (result != null) {
					setPerson(result.getResult());
				}
			}
		});
	}

	public void setPerson(PersonDto person) {
		this.person = person;

		if (this.person != null) {
			updateViewData();
		} else {
			clearView();
		}
	}

	protected void updateViewData() {
		clearView();

		PersonNameDto personName = person.getPersonName();
		if (personName != null) {
			display.getFirstNameData().setText(personName.getFirstName());
			display.getLastNameData().setText(personName.getLastName());
			display.getSurnameData().setText(personName.getSurName());
		}

		ContactInfoDto contactInfo = person.getContactInfo();
		if (contactInfo != null) {
			display.getEmailData().setText(contactInfo.getEmail());
			display.getTelephoneData().setText(contactInfo.getTelephone());
			display.getWebsiteData().setText(contactInfo.getWebSite());

			AddressDto address = contactInfo.getAddress();
			if (address != null) {
				display.getCityData().setText(address.getCity());
				display.getCountryData().setText(address.getCountry());
				display.getStreetData().setText(address.getStreet());
			}
		}
	}

	public TargetDto getTarget() {
		return target;
	}
}
